#include "polsys_misc.h"

// 4字节求和校验数据包，32位校验和在最后4字节(小端排列)
// len应该是4的倍数
// buff所指向的地址必须4的倍数，否则会出现寻址错误引发 HardFault
bool SumU32_Verify(const u8 *buff, u32 len)
{
	u32 i;
	u32 sum = 0;
	u32 len32 = len/4;
	const u32 *buff32 = (const u32 *)buff;
	for (i = 0; i < len32-1; i++)
	{
		sum += buff32[i];
	}
	return (sum == buff32[i]);
	// for (i = 0; i < len-4; i+=4)
	// {
	// 	sum += *(u32 *)(buff+i);
	// }
	// return (sum == *(u32 *)(buff+i));
}

// 获得32位校验和
u32 GetSum_U32(const u8 *buff, u32 len)
{
	u32 i;
	u32 sum = 0;
	for (i = 0; i < len; i++)
	{
		sum += buff[i];
	}
	return sum;
}

// 获得8位校验和
u8 GetSum_U8(const u8 *buff, u8 len)
{
	u8 i;
	u8 sum = 0;
	for (i = 0; i < len; i++)
	{
		sum += buff[i];
	}
	return sum;
}

static pdata u32 mRand; // 8bit伪随机数 mRand掉电保存随机性更强
// 生成8bit随机数
u8 GetRand8bit(void)
{
	u32 temp = mRand;
	do
	{
		// 防止为0
		if (temp == 0)
			temp = 0x4B07;
		temp ^= (temp << 13);
		temp ^= (temp >> 17);
		temp ^= (temp << 5);
		mRand = temp;
		temp = (temp >> 16) & 0x00FF;
	} while (temp == 0);
	// 保存mRand;
	return (u8)(temp);
}

bool IsInRangeU16(u16 num, u16 start, u16 end)
{
	return ((num >= start) && (num <= end));
}

////把数据分离成单个字节，高字节在前（0）
//void SplitDWard(u32 a,u8 * b)
//{
//		b[3] = (u8)(a >> 24);
//		b[2] = (u8)(a >> 16);
//		b[1] = (u8)(a >> 8);
//		b[0] = (u8)a;
//}

//把字节数组的成员合并成1个u32整数 0[3] 1[2] 2[1] 3[0]
u32 MakeU32(u8 *Bytes, u8 Lenght)
{
	u8 yw = 0;
	u8 index;
	u32 r = 0;
	u8 i;

	if (Lenght > 4)
		return 0;
	index = Lenght - 1;

	for (i = 0; i < Lenght; i++)
	{
		r += ((u32)Bytes[index] << yw);
		yw += 8;
		index--;
	}
	return r;
}

/****************************************************************************
* 名    称：u8 dec_to_bcd(u8 dat)
* 功    能：将普通数据转换成高4位存放十位，低4位存放个位的BCD码。
* 入口参数：dat：想要转换的数据
* 出口参数：转换完成的数据
* 说    明：如 55-->0x55
* 调用方法：bcdnum=dec_to_bcd(num);
****************************************************************************/
u8 dec_to_bcd(u8 dat)
{
	u8 temp;
	temp = dat / 10;
	dat = dat % 10;
	temp = (temp << 4) + dat;
	return temp;
}
/****************************************************************************
* 名    称：u8 bcd_to_dec(u8 dat)
* 功    能：将高4位存放十位，低4位存放个位的BCD码转换为普通数据。
* 入口参数：dat：想要转换的数据
* 出口参数：转换完成的数据
* 说    明：如 0x55-->55
* 调用方法：num=bcd_to_dec(bcdnum);
****************************************************************************/
u8 bcd_to_dec(u8 dat)
{
	u8 dat1;
	dat1 = dat / 16;
	dat = dat % 16;
	dat1 = dat + dat1 * 10;
	return dat1;
}
/*********************************************************************
* 名    称: u16 MedianFilter16b9(u16 *dat)
* 功    能: 中值滤波
* 入口参数: 数组首地址
* 出口参数: 结果
* 说    明: 16bit 9次
* 调用方法: ADVolue = MedianFilter16b9(datbuff);
**********************************************************************/
u16 MedianFilter16b9(u16 *dat)
{
	u8 i, j, k;
	u16 temp;

	for (i = 0; i < 8; i++) //排序
	{
		k = i;
		for (j = k + 1; j < 9; j++)
		{
			if (dat[k] > dat[j])
				k = j;
		}
		temp = dat[k];
		dat[k] = dat[i];
		dat[i] = temp;
	}
	temp = ((u32)dat[3] + (u32)dat[4] + (u32)dat[5]) / 3; //取中间值
	return (temp);
}

/************************************************************************************************
* 名    称：void ToString(char * str,float dat,const char * fmt)
* 功    能：将数字转换为希望格式的字符串。
* 入口参数：str - 转换后的字符串存放的首地址
			dat - 要转换的数
			fmt - 格式
				例："3.4D"
				'3'	- 整数部分长度
				'4'	- 小数部分长度
				'D' - 十进制
					(其他进制：		'H' - 十六进制
								 	'B' - 二进制	   )
* 出口参数：
* 说    明：功能还未全部完善。
* 调用方法：ToString(str,dat,"4D");
*************************************************************************************************/
/*
void ToString(char * str,float dat,const char * fmt)
{	   	 
	int ZhengShu,XiaoShu;
	int i,temp;
	unsigned char j=0;
	unsigned char xiaoshu,zhengshu,lengh;
	char format;
	//处理格式
	if(*fmt=='.')
	{
		zhengshu = 0;
		xiaoshu = *(fmt+1)-'0';
		format = *(fmt+2);
	}
	else
	{
		zhengshu = *fmt-'0';
		if(*(fmt+1)=='.')
		{
			xiaoshu = *(fmt+2)-'0';
			format = *(fmt+3);
		}
		else 
		{
			xiaoshu = 0;
			format = *(fmt+1);
		}
	}
	lengh = xiaoshu+zhengshu+1;
	//处理数据
	if(dat<0)    //正负判断
	{
		str[j++] = '-';
		dat=-dat;
	}		   
	ZhengShu = (int)dat;
	for(temp=1;xiaoshu>0;xiaoshu--)temp=temp*10;
	XiaoShu = (int)(dat*temp);
	XiaoShu = XiaoShu%temp;
	//开始转换
	switch(format)
	{
		case 'D': 
				if(ZhengShu)
				{
					for(i=1;zhengshu>1;zhengshu--)i=i*10;
					for(;ZhengShu/i==0;i=i/10);
					for(;i>0;i=i/10)
					{
						str[j++] = ZhengShu/i+'0';
						ZhengShu = ZhengShu%i;
					}
				}
				else
				{
					str[j++]='0';
				}
				if(XiaoShu)
				{
					str[j++]='.';
					temp=temp/10;
					for(;XiaoShu/temp==0;temp=temp/10);
					for(;temp>0;temp=temp/10)
					{
						str[j++] = XiaoShu/temp+'0';
						XiaoShu = XiaoShu%temp;
					}
				}
				break;
		default:break;
	}
	//补空格，LCD显示需要
	while(j<lengh)
	{
		str[j++]=' ';
	}
	str[j]='\0';
} 	*/
